delta = 0.31

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(isolation_mos()

prog( () 
	
	declare(coord_reference[4])  
	coord_reference[0] = 0.0	
	coord_reference[1] = 0.0	
	coord_reference[2] = 0.0	
	coord_reference[3] = 0.0
	liste_type_cell  = '()	
	x_min = '()
	y_min = '()
	x_max = '()
	y_max = '()	
	flag_erreur = nil

		cv = geGetWindowCellView() 
		liste_id = geGetSelSet()

		for(i 0 length(liste_id)-1
		    liste_type_cell = append1(liste_type_cell nth(i liste_id)~>cellName) 	
		)

		for(i 0 length(liste_id)-2
			a = nth(i liste_type_cell)
			b = nth(i+1 liste_type_cell)
			if(a != b then
			   printf("[Info]:Erreur - type de mos non homogenes !.\n")
			   flag_erreur = t
			   return("stop") 
			)
		)

		;; determine le type de mos
		chaine = ""
		chaine = nth(0 liste_type_cell)

		if( strncmp( "p" chaine 1) == 0 then
		    type_ring = "N" 
		    layer_detection = "PIMP"	
		    layer_implant = "PIMP"
		)
		if( strncmp( "n" chaine 1) == 0 then
		    type_ring = "P" 
		    layer_detection = "NIMP"	
		    layer_implant = "NIMP"
		) 
	
		largeur_ring = (0.24 + 0.05 + 0.14 + 0.46)*2

		for(i 0 length(liste_id)-1

		    	coord = nth(i liste_id)~>xy
			contenu = nth(i liste_id)~>master~>shapes
		        nbre_shape = length(contenu)
			;type_cell = nth(i liste_id)~>cellName
		    	;liste_type_cell = append1(liste_type_cell type_cell) 	

		    	for(j 0 (nbre_shape-1)
				if(nth(j contenu)~>layerName == layer_detection && nth(j contenu)~>purpose == "drawing" then
			               enveloppe = nth(j contenu)~>bBox
	    		   	       coord = nth(i liste_id)~>xy
					   x0 = car(coord)
					   y0 = cadr(coord)
				   xmin = car(car(enveloppe)) + x0
				   ymin = cadr(car(enveloppe)) + y0	
				   xmax = car(cadr(enveloppe)) + x0
				   ymax = cadr(cadr(enveloppe))	+ y0

				   x_min = append1(x_min xmin) 
				   y_min = append1(y_min ymin) 
				   x_max = append1(x_max xmax) 
				   y_max = append1(y_max ymax) 			

				   printf("Box %L %L %f %f %f %f\n" enveloppe coord xmin ymin xmax ymax)
				)
	    	         )

		  )	

			for(j 0 length(liste_id)-1-1
			    if(j == 0 then  
				a = nth(j x_min)
				b = nth(j+1 x_min)
				val = min(a b)
			    )
			    if(j > 0 then  
				a = nth(j x_min)
				val = min(val a)
			    )
			)
			coord_reference[0] = val 
	
			for(j 0 length(liste_id)-1-1
			    if(j == 0 then  
				a = nth(j y_min)
				b = nth(j+1 y_min)
				val = min(a b)
			    )
			    if(j > 0 then  
				a = nth(j y_min)
				val = min(val a) 
			    )
			)
			coord_reference[1] = val 


			for(j 0 length(liste_id)-1-1
			    if(j == 0 then  
				a = nth(j x_max)
				b = nth(j+1 x_max)
				val = max(a b)
			    )
			    if(j > 0 then  
				a = nth(j x_max)
				val = max(val a)
			    )
			)
			coord_reference[2] = val 
	
			for(j 0 length(liste_id)-1-1
			    if(j == 0 then  
				a = nth(j y_max)
				b = nth(j+1 y_max)
				val = max(a b)
			    )
			    if(j > 0 then  
				a = nth(j y_max)
				val = max(val a)
			    )
			)
			coord_reference[3] = val 

			dbCreateRect( cv list(layer_implant "drawing") list(coord_reference[0]-delta:coord_reference[1]-delta coord_reference[2]+delta:coord_reference[3]+delta) )
		
			;largeur_demi_ring = 1.78 / 2
			largeur_demi_ring = 0.45 + 0.29
	
			x1 = coord_reference[0] - largeur_demi_ring
		        y1 = coord_reference[1] + 2
	
		        x2 = coord_reference[0] - largeur_demi_ring
		        y2 = coord_reference[3] + largeur_demi_ring

			x3 = coord_reference[2] + largeur_demi_ring
		        y3 = coord_reference[3] + largeur_demi_ring

			x4 = coord_reference[2] + largeur_demi_ring
		        y4 = coord_reference[1] - largeur_demi_ring
	
			x5 = coord_reference[0] - largeur_demi_ring
		        y5 = coord_reference[1] - largeur_demi_ring

			x6 = x1
		        y6 = y1  

			coord_ring = '()
		        coord_ring = list(x1:y1 x2:y2 x3:y3 x4:y4 x5:y5 x6:y6 ) 	
			retour = rod_ring(coord_ring 1 type_ring)


			;if(type_ring = "N" then
			;   xa = x5 - largeur_ring/2
			;   ya = y5 - largeur_ring/2 	
			;   xb = x2 - largeur_ring/2
			;   yb = y2 + largeur_ring/2 	
			;   xc = x3 + largeur_ring/2
			;   yc = y3 + largeur_ring/2 	
			;   xd = x4 + largeur_ring/2
			;   yd = y4 - largeur_ring/2 		
			;   coord_nw = list("")
		        ;   coord_nw = list(xa:ya xb:yb xc:yc xd:yd) 
			;   dbCreateRect( cv "nw" list(xa:ya xc:yc) )
			;) 
	);prog

)
;#############################################################################################
procedure(rod_ring(coord nombre_contact type_ring)

   prog( ()

   let((stock total)

	cv = geGetWindowCellView() 

	declare(tab[nombre_contact])
        space = '()

        largeur_contact = 0.30
        espace_contact = 0.30
        retrait_contact = 0.09
        largeur_couche_active = (nombre_contact*largeur_contact) + (nombre_contact-1)*espace_contact + (2*retrait_contact) 
        espace_inter_contact = largeur_contact + espace_contact 

        if(nombre_contact == 1 then
           tab[0] = 0
        );

        if(nombre_contact > 1 then

           parite = oddp(nombre_contact)
           if(parite == t then	;;; impair
              rangee = (nombre_contact-1)/2
              tab[0] = 0
              for( j 1 rangee
                   tab[j] = j*espace_inter_contact
              )
              for( k 1 rangee
                   tab[rangee+k] = -k*espace_inter_contact
              )
              for( l 0 nombre_contact-1
                   stock = append1(stock tab[l])
              )
           )

           if(parite == nil then  ;;; pair
              rangee = nombre_contact/2
              for( j 1 rangee
                   if(j == 1 then
                      tab[j-1] = espace_inter_contact/2
                   else tab[j-1] = tab[j-2] + espace_inter_contact
                   )
              )
              for( k 1 rangee
                   if(k == 1 then
                      tab[rangee+k-1] = -espace_inter_contact/2
                   else        tab[rangee+k-1] = tab[rangee+k-2] - espace_inter_contact
                   )
              )
              for( l 0 nombre_contact-1
                   stock = append1(stock tab[l])
              )
           )

        )

        for(m 0 nombre_contact-1

              ;espace = nth(m space)
              espace = tab[m]
              infos = list( ?layer             list("CONT" "drawing")
                            ?width             0.30
                            ?length            0.30
                            ?choppable         nil
                            ?sep               espace
                            ?justification     "center"
                            ?space             0.30
                            ?beginOffset       -0.20
                            ?endOffset         -0.20
                            ?beginSegOffset    0.30
                            ?endSegOffset      0.30
                            ?gap               "distribute"
                        )

        total = append1(total infos)

        )
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     			if( type_ring == "N" then

		            id_rod = rodCreatePath(
                				    ?cvId    		cv
				                    ?layer         	list("METAL1" "drawing")
				                    ?width         	largeur_couche_active
              					    ?pts         	coord
					            ?choppable         	nil
					            ?endType         	"flush"
					            ?beginExt         	0.00
					            ?endExt         	0.00
					            ?justification      "center"
					            ?offset         	0.00
					            ?encSubPath
                				    list(
			    				 list(
				                                ?layer         list("DIFF" "drawing")
                                				?enclosure     -0.05
                                				?choppable     nil
                                				?beginOffset   0.00
                                				?endOffset     0.00
                            				 )
			 				 list(
				                                ?layer         list("NIMP" "drawing")
                                				?enclosure     -0.19
                                				?choppable     nil
                                				?beginOffset   0.00
                                				?endOffset     0.00
                            				 )
							 list(
                                				?layer         list("NWELL" "drawing")
				                                ?enclosure     -0.65
                                				?choppable     t
				                                ?beginOffset   0.00
				                                ?endOffset     0.00
			                                 )
			
				                  )
				                ?subRect         total 

			                    )

		      )


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		    if( type_ring == "P" then

		            id_rod = rodCreatePath(
                				    ?cvId    		cv
				                    ?layer         	list("METAL1" "drawing")
				                    ?width         	largeur_couche_active
              					    ?pts         	coord
					            ?choppable         	nil
					            ?endType         	"flush"
					            ?beginExt         	0.00
					            ?endExt         	0.00
					            ?justification      "center"
					            ?offset         	0.00
					            ?encSubPath
                				    list(
			    				 list(
				                                ?layer         list("DIFF" "drawing")
                                				?enclosure     -0.05
                                				?choppable     nil
                                				?beginOffset   0.00
                                				?endOffset     0.00
                            				 )
			 				 list(
				                                ?layer         list("PIMP" "drawing")
                                				?enclosure     -0.19
                                				?choppable     nil
                                				?beginOffset   0.00
                                				?endOffset     0.00
                            				 )
			
				                  )
				                ?subRect         total 

			                    )

		      )


   );let

	return(list(id_rod))

   );prog

); procedure
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
procedure(main()

	retour = isolation_mos()
	if(retour == "stop" then
		  printf("[Info]: Aborded traitement. \n")
	else 
		  printf("[Info]: Traitement done. \n")
	) 

)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
hiSetBindKey("Layout" "Shift<Key>o" "main()")


 
